延續上一篇(中篇),我們繼續製作 專屬的 Agent P!
話不多說,我們正文開始,準備見證 Agent P 的誕生(。・∀・)ノ
請先確認上篇與中篇內容都有用出來喔!
不了解 FastAPI 的 可以參考 Day 10 與 Day 12,這裡就不再多說~
現在我們將之前撰寫好的 Root Agent 包裝成 API 端點:
load_dotenv()
app = FastAPI()
# CORS 設定
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
session_service = InMemorySessionService()
artifacts_service = InMemoryArtifactService()
class QueryRequest(BaseModel):
query: str
@app.post("/query")
async def handle_query(request: QueryRequest):
try:
session = await session_service.create_session(
state={},
app_name="my_app",
user_id="user"
)
parts = [types.Part(text=request.query)]
content = types.Content(role="user",parts=parts)
runner = Runner(
app_name="my_app",
agent=root_agent,
session_service=session_service,
artifact_service=artifacts_service
)
events_async = runner.run_async(
session_id=session.id,
user_id="user",
new_message=content
)
response = []
async for event in events_async:
if event.content:
for part in event.content.parts:
if part.text:
response.append(part.text)
root_agent_response = "\n".join(response)
return {
"response": root_agent_response
}
except Exception as e:
return {"error": str(e)}
因為之前也有介紹過,這裡也不揚細說明~ 可以參考 Day 14
一個簡單的網頁互動介面:
import gradio as gr
import requests
# 向你的 FastAPI 發送對話請求
def multi_tool_chat(message, history):
try:
# 呼叫你的 FastAPI /query 端點
url = "http://localhost:8080/query"
payload = {
"query": message
}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 200:
data = response.json()
if "response" in data:
return data["response"]
elif "error" in data:
return f"⚠️ 服務錯誤:{data['error']}\n\n別擔心,我們的技術團隊正在處理中。您可以稍後再試,或者先和我簡單聊聊天 😊"
else:
return "收到了回應,但格式有點特殊,讓我重新整理一下資訊給您 🤔"
else:
return f"🌐 連線問題 (HTTP {response.status_code})\n\n看起來網路有點不穩定,建議您稍後再試。期間如果想聊天,我隨時歡迎!"
except requests.exceptions.Timeout:
return "⏰ 查詢超時了\n\n網路可能比較慢,請稍等一下再試。如果持續有問題,可能是服務正在維護中 🔧"
except requests.exceptions.ConnectionError:
return """❌ 無法連接到服務
看起來 Agent P 的服務暫時離線了 😔
**您可以嘗試:**
1. 檢查 FastAPI 服務是否在運行 (http://localhost:8080)
2. 重新啟動服務後再試
3. 如果問題持續,可能需要檢查網路設定
**期間您也可以:**
- 直接使用手機查詢天氣
- 開啟 Spotify App 播放音樂
- 前往 HackMD 網站管理筆記
- 使用 Google 搜尋查詢資訊
- 或者就在這裡和我隨意聊聊 😊
我會持續嘗試重新連接服務!"""
except Exception as e:
return f"""😅 發生了意外錯誤
錯誤詳情:{str(e)}
別擔心,這些技術問題總是會解決的!
您可以:
1. 稍後重試
2. 重新整理頁面
3. 先在這裡隨意聊聊
我們的服務通常很穩定,可能只是暫時的小問題"""
# 建立最簡單的聊天介面
demo = gr.ChatInterface(
fn=multi_tool_chat,
title="專屬助理 Agent P",
description="""
我是你的專屬助理 Agent P!
**功能示範:**
天氣查詢:「台北天氣如何」「東京現在幾點」
音樂控制:「播放周杰倫」「建立播放清單」
筆記管理:「列出我的筆記」「建立新筆記」
網路搜尋:「搜尋最新新聞」「查詢比特幣價格」
日常對話:「你好」「謝謝」「我很累」
即使遇到技術問題,我們也會用最溫暖的方式為您服務!
""",
examples=[
"你好 P!",
"台北天氣如何?",
"播放一些輕音樂",
"列出我的所有筆記",
"建立一個會議記錄筆記",
"我的 HackMD 使用者資訊",
"搜尋台積電最新新聞",
"查詢比特幣價格",
"找資料:人工智慧發展趨勢",
"讀取網頁內容",
"搜尋流行音樂",
"建立一個放鬆音樂播放清單",
"台中的溫度和濕度",
"謝謝你的幫助"
],
theme="soft" # 使用溫暖的主題
)
if __name__ == "__main__":
print("🚀 啟動 P 的多功能助理服務...")
print()
print("📋 啟動前檢查清單:")
print(" ✅ FastAPI 服務運行於 http://localhost:8080")
print(" ✅ HackMD API Token 已設定")
print(" ✅ Spotify 認證已完成")
print(" ✅ SearXNG 服務運行於 http://localhost:8888")
print(" ✅ MCP-SearXNG 服務運行於 http://localhost:5488")
print(" ✅ 所有 MCP Server 可正常運作")
print()
print("🌐 Gradio 介面即將在瀏覽器中打開")
print("💫 多功能助理團隊準備就緒,為您提供專業服務!")
demo.launch()
# 進入 Docker 目錄
cd ...\searxng-docker
# 檢查 docker-compose.yaml 是否存在
dir docker-compose.yaml
# 啟動 SearXNG 服務(背景運行)
docker compose up -d
# 驗證服務狀態
docker compose ps
# 回到 mcp-searxng 目錄
cd ...\mcp-searxng or cd ..
# 啟動 MCP Server(如果你想使用 MCP 協議的話)
python server.py --searxng_url="http://localhost:8888"
# 進入主專案目錄
# 確認虛擬環境已啟動
.venv\Scripts\activate
# 啟動 FastAPI 服務
uvicorn main:app --host 0.0.0.0 --port 8080
# 開新終端,進入主專案目錄
# 啟動虛擬環境
.venv\Scripts\activate
# 啟動 Gradio 介面
python gradio_app.py
# 關閉SearXNG 服務
docker compose down
恭喜大家做出 Agent P~ (ノ◕ヮ◕)ノ*:・゚✧
大家可以依據自己的喜好去更改自己的 Prompt 等,做出符合自己需求,真正屬於自己的 Agent~
更多 Model Context Protocol servers可以自行搜尋、使用~
我們最後一篇見~ o(=•ェ•=)m